#include <workflow/Workflow.h>
#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/HttpUtil.h>
#include <unistd.h>
#include <signal.h>
#include <ctime>
#include <iostream>
#include <vector>
using std::cerr;
using std::cout;
using std::string;
using std::vector;

struct SeriesContext
{
    string url;
    
    size_t body_len;
};

// 定义全局变量
static WFFacilities::WaitGroup waitGroup(1);

void signalhandler(int signum)
{
    waitGroup.done(); // 每done一次，等待的n就-1
}

void httpCallback(WFHttpTask *task)
{
    protocol::HttpResponse *resp = task->get_resp(); // 获取第二个模板参数，即响应
    SeriesContext *context = static_cast<SeriesContext *>(series_of(task)->get_context());

    const void *body; // 通用指针类型，适配任意数据
    size_t body_len;

    resp->get_parsed_body(&body, &body_len); // 让body指向报文体的首地址
    context->body_len = body_len;
    cerr << "url = " << context->url << " "
         << "body len = " << context->body_len << "\n";
}

void parallelCallback(const ParallelWork * parallelWork){
    string url;
    size_t body_len = 0;
    for(int i=0; i<parallelWork->size(); i++){
        SeriesContext * context = static_cast<SeriesContext *>(parallelWork->series_at(i)->get_context());
        if (body_len < context->body_len){
            url = context->url;
            body_len = context->body_len;
        }
        delete context;
    }
    cerr << "longest url = " << url << " " << "body_len = " << body_len << "\n";
    WFRedisTask * redisTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379", 10, nullptr);
    redisTask->get_req()->set_request("set", {url, std::to_string(body_len)});
    series_of(parallelWork)->push_back(redisTask);
}

int main()
{
    signal(SIGINT, signalhandler);
    vector<string> urls = {"http://www.taobao.com", "http://www.jd.com", "http://www.baidu.com"};

    ParallelWork *parallelWork = Workflow::create_parallel_work(parallelCallback);

    for (int i = 0; i < 3; i++)
    {
        WFHttpTask *httpTask = WFTaskFactory::create_http_task(urls[i], 10, 10, httpCallback);

        // 创建了小序列
        SeriesWork *series = Workflow::create_series_work(httpTask, nullptr);

        // 申请contex
        SeriesContext *context = new SeriesContext;
        series->set_context(context);
        context->url = urls[i];

        // 将小序列加入到并行任务中
        parallelWork->add_series(series);
    }

    parallelWork->start();

    waitGroup.wait();
    cout << "finished!\n";

    return 0;
}